<html>

<head>
  <title>常用材质</title>
  <style>
    body {
      margin: 0;
    }

    canvas {
      display: block;
    }
  </style>
</head>

<body>
  <script src="./js/three.js"></script>
  <script src="./js/OrbitControls.js"></script>
  <script>
    // 1、创建场景
    var scene = new THREE.Scene();

    //创建一个球体几何对象
    var geometry = new THREE.BoxGeometry(100, 100, 100);

    /* 
      材质Material：
          1、点材质：PointsMaterial
          2、线材质：构造函数首字母Line开头材质
            2.1、线基础材质：LineBasicMaterial
            2.2、虚线材质：LineDashedMaterial
          3、网格材质：构造函数首字母Mesh开头材质
            3.1、网格基础材质：MeshBasicMaterial
            3.2：网格Lambert材质、暗淡、漫反射：MeshLambertMaterial
            3.3、网格Phong材质、高亮表面、镜面反射：MeshPhongMaterial
            3.4、PBR材质：MeshStandardMaterial、MeshPhysicalMaterial、比MeshPhongMaterial效果更好
            3.5、网格深度材质：MeshDepthMaterial
            3.6、网格法向量材质：MeshNormalMaterial
          4、精灵Sprite材质：SpriteMaterial
          5、自定义着色器材质：RawShaderMaterial、ShaderMaterial
    */

    // ==============================================================================================================
    // 材质对象
    // var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
    // 网格模型对象Mesh
    // var cube = new THREE.Mesh(geometry, material);
    // scene.add(cube);

    // =============================================================================================================
    // 点材质PointsMaterial的.size属性可以每个顶点渲染的方形区域尺寸像素大小。
    // 创建一个点材质对象
    // var material = new THREE.PointsMaterial({
    //   color: 0x0000ff, //颜色
    //   size: 3, //点渲染尺寸
    // });
    //点模型对象  参数：几何体  点材质
    // var cube = new THREE.Points(geometry, material);
    // scene.add(cube); //网格模型添加到场景中

    // =============================================================================================================
    //基础线材质LineBasicMaterial。 
    // 直线基础材质对象
    // var material = new THREE.LineBasicMaterial({
    //   color: 0x0000ff
    // });
    // var cube = new THREE.Line(geometry, material); //线模型对象
    // scene.add(cube); //线模型添加到场景中

    // 虚线材质LineDashedMaterial。
    // 虚线材质对象：产生虚线效果
    // var material = new THREE.LineDashedMaterial({
    //   color: 0x0000ff,
    //   dashSize: 10,//显示线段的大小。默认为3。
    //   gapSize: 5,//间隙的大小。默认为1
    //   linewidth: 1,
    //   scale: 1,
    // });
    // var cube = new THREE.Line(geometry, material); //线模型对象
    //  computeLineDistances方法  计算LineDashedMaterial所需的距离数组
    // cube.computeLineDistances();
    // scene.add(cube);

    // =============================================================================================================
    // 网格材质
    // 基础网格材质对象MeshBasicMaterial,不受带有方向光源影响，没有棱角感。
    // var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
    // var cube = new THREE.Mesh(geometry, material);
    // scene.add(cube);

    // MeshLambertMaterial材质可以实现网格Mesh表面与光源的漫反射光照计算，有了光照计算，物体表面分界的位置才会产生棱角感。
    // var material = new THREE.MeshLambertMaterial({
    //   color: 0x00ff00,
    // });
    // var cube = new THREE.Mesh(geometry, material);
    // scene.add(cube);

    // 高光网格材质MeshPhongMaterial除了和MeshLambertMaterial一样可以实现光源和网格表面的漫反射光照计算，还可以产生高光效果(镜面反射)。
    // var material = new THREE.MeshPhongMaterial({
    //   color: 0xff0000,
    //   specular: 0x444444,//高光部分的颜色
    //   shininess: 20,//高光部分的亮度，默认30
    //   side: THREE.DoubleSide,
    // });
    // var cube = new THREE.Mesh(geometry, material);
    // scene.add(cube);


    // =============================================================================================================
    // 材质共有属性、私有属性
    // .side属性的属性值定义面的渲染方式前面后面 或 双面.
    //  属性的默认值是THREE.FrontSide，表示前面. 也可以设置为后面THREE.BackSide 或 双面THREE.DoubleSide.
    // var material = new THREE.MeshBasicMaterial({
    //   color: 0xdd00ff,
    //   // 前面FrontSide  背面：BackSide 双面：DoubleSide
    //   side: THREE.DoubleSide,
    // });
    // var cube = new THREE.Mesh(geometry, material);
    // scene.add(cube);

    // 材质透明度.opacity
    /* 
    通过材质的透明度属性.opacity可以设置材质的透明程度，.opacity属性值的范围是0.0~1.0，0.0值表示完全透明, 1.0表示完全不透明，.opacity默认值1.0。
    当设置.opacity属性值的时候，需要设置材质属性transparent值为true，如果材质的transparent属性没设置为true, 材质会保持完全不透明状态。
    */
    // var material = new THREE.MeshPhongMaterial({
    // color: 0x220000,
    // transparent设置为true，开启透明，否则opacity不起作用
    // transparent: true,
    // 设置材质透明度
    // opacity: 0.4,
    // });
    // 通过访问材质对象属性形式设置transparent和.opacity的属性值
    // transparent设置为true，开启透明，否则opacity不起作用
    // material.transparent = true;
    // 设置材质透明度
    // material.opacity = 0.4;

    // var cube = new THREE.Mesh(geometry, material);
    // scene.add(cube);

    // =============================================================================================================
    // 精灵Sprite材质
    // var texture = new THREE.TextureLoader().load("./img/1.jpg");
    // 创建精灵材质对象SpriteMaterial
    // var spriteMaterial = new THREE.SpriteMaterial({
    //   color: 0xffffff,//设置精灵矩形区域颜色
    //   rotation: Math.PI / 4,//旋转精灵对象45度，弧度值
    //   map: texture,//设置精灵纹理贴图
    // });
    // 创建精灵模型对象，不需要几何体geometry参数
    // var cube = new THREE.Sprite(spriteMaterial);
    // scene.add(cube);
    // 控制精灵大小，比如可视化中精灵大小表征数据大小
    // cube.scale.set(100, 100, 100); //// 只需要设置x、y两个分量就可以

    // =============================================================================================================
    // 纹理贴图映射到一个矩形平面上
    var cube;
    // var geometry = new THREE.PlaneGeometry(204, 102); //矩形平面
    // var geometry = new THREE.BoxGeometry(100, 100, 100); //立方体
    var geometry = new THREE.SphereGeometry(60, 100, 100); //球体
    // TextureLoader创建一个纹理加载器对象，可以加载图片作为几何体纹理
    var textureLoader = new THREE.TextureLoader();
    // 执行load方法，加载纹理贴图成功后，返回一个纹理对象Texture
    textureLoader.load('./img/1.jpg', function (texture) {
      var material = new THREE.MeshLambertMaterial({
        // color: 0x0000ff,
        // 设置颜色纹理贴图：Texture对象作为材质map属性的属性值
        map: texture,//设置颜色贴图属性值
      }); //材质对象Material
      cube = new THREE.Mesh(geometry, material); //网格模型对象Mesh
      scene.add(cube); //网格模型添加到场景中

      //纹理贴图加载成功后，调用渲染函数执行渲染操作
      // render();
    })



    // 3、光源设置：
    //环境光    环境光颜色与网格模型的颜色进行RGB进行乘法运算
    var ambient = new THREE.AmbientLight('#444444');
    scene.add(ambient);

    //点光源  
    var point = new THREE.PointLight(0xffffff);
    point.position.set(400, 200, 300);
    scene.add(point);


    // 4、添加相机
    var width = window.innerWidth; //窗口宽度
    var height = window.innerHeight; //窗口高度
    var k = width / height; //窗口宽高比
    var s = 200; //三维场景显示范围控制系数，系数越大，显示的范围越大
    var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
    camera.position.z = 5;
    //设置相机位置
    camera.position.set(200, 300, 200);
    //设置相机方向(指向的场景对象)
    camera.lookAt(scene.position);


    // 5、创建渲染器对象
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    // renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
    document.body.appendChild(renderer.domElement);

    // 6、执行渲染操作
    var animate = function () {
      renderer.render(scene, camera);
      requestAnimationFrame(animate);
      // cube.rotation.x += 0.01;
      // cube.rotation.y += 0.01;
    };
    animate();
    var controls = new THREE.OrbitControls(camera);//创建控件对象
  </script>
</body>

</html>